package com.hzcc.hzccblog.module.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hzcc.hzccblog.common.Result;
import com.hzcc.hzccblog.common.enums.LoginEnums;
import com.hzcc.hzccblog.common.enums.PublicEnums;
import com.hzcc.hzccblog.module.dao.UserDao;
import com.hzcc.hzccblog.module.entity.dto.RegisterDto;
import com.hzcc.hzccblog.module.entity.dto.UserLoginDto;
import com.hzcc.hzccblog.module.entity.po.User;
import com.hzcc.hzccblog.module.entity.vo.LoginUser;
import com.hzcc.hzccblog.module.service.LoginService;
import com.hzcc.hzccblog.module.service.UserService;
import com.hzcc.hzccblog.utils.CodeUtil;
import com.hzcc.hzccblog.utils.IDUtil;
import com.hzcc.hzccblog.utils.JWTUtil;
import com.hzcc.hzccblog.utils.RedisUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.regex.Pattern;

import static com.hzcc.hzccblog.common.Constant.*;
import static com.hzcc.hzccblog.common.Constant.LOGIN_TOKEN;

/**
 * @Author 早睡蛋
 * @Date 2022/7/18 14:03:07
 * @Desc:
 */
@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private UserDao userDao;
    @Resource
    private RedisUtil redisUtil;

    public final static Long tokenExp = (long)(60*60*24*7);


    /**
     * 用户注册验证
     * @param registerDto
     * @return
     */
    @Override
    public Result userRegister(RegisterDto registerDto) {
        String rexEmail = EMAIL_REX;
        boolean matches = Pattern.matches(rexEmail, registerDto.getUserEmail());
        if (!matches){
            return LoginEnums.EMAIL_REX.getResult();
        }
        QueryWrapper<User> findByUserEmail = new QueryWrapper<>();
        findByUserEmail.select("user_email").eq("user_email",registerDto.getUserEmail());
        User user = userDao.selectOne(findByUserEmail);
        if (user!=null){
            return LoginEnums.EMAIL_EXIST.getResult();
        }
        String userEmail = registerDto.getUserEmail();
        String code = registerDto.getCode();
        String redisCode = redisUtil.getString(REGISTER_CODE + userEmail);
        if (redisCode==null){
            return LoginEnums.MSM_NULL.getResult();
        }
        if (!redisCode.equals(code)){
            return LoginEnums.MSM_FAIL.getResult();
        }
        User newUser = new User();
        newUser.setId(IDUtil.createByUUID());
        newUser.setUserName(registerDto.getUserName());
        newUser.setUserEmail(registerDto.getUserEmail());
        String salt = CodeUtil.getCode();
        String pwd = DigestUtils.md5DigestAsHex((registerDto.getPassword()+salt).getBytes());
        newUser.setPassword(pwd);
        newUser.setSalt(salt);
        newUser.setCreateTime(String.valueOf(System.currentTimeMillis()));
        newUser.setUpdateTime(String.valueOf(System.currentTimeMillis()));
        int insert = userDao.insert(newUser);
        if (insert>0){
            redisUtil.delString(REGISTER_CODE + userEmail);
            return  LoginEnums.REGISTER_OK.getResult();
        }else {
            return  LoginEnums.REGISTER_FAIL.getResult();
        }
    }

    /**
     * 用户登录
     * @param userLoginDto
     * @return
     */
    @Override
    public Result userLogin(UserLoginDto userLoginDto) {
        UsernamePasswordToken token = new UsernamePasswordToken(userLoginDto.getUserEmail(),userLoginDto.getPassword());
        // 认证身份
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            // 登录成功则返回token，用于无状态会话
            String access_token = subject.getSession().getId().toString();
            LoginUser loginUser = new LoginUser();
            loginUser.setUserName(userLoginDto.getUserEmail());
            loginUser.setToken(access_token);
            redisUtil.setStringExpire(LOGIN_TOKEN+userLoginDto.getUserEmail(),access_token,(long)(60*60*24*7));
            return LoginEnums.LOGIN_OK.getResult().setData(loginUser);
            // 设置session时间
            //SecurityUtils.getSubject().getSession().setTimeout(1000*60*30);

        } catch (AccountException e){
            return LoginEnums.LOGIN_FAIL.getResult();
        } catch (Exception e) {
            return LoginEnums.LOGIN_FAIL.getResult();
        }
    }

    /**
     * 登出
     * @param request
     * @return
     */
    @Override
    public Result userLogout(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        String userToken = token.substring(0,token.length()-1);
        Map<String, Object> stringObjectMap = JWTUtil.verify1(userToken);
        String email = (String) stringObjectMap.get("email");
        System.out.println(email);
        redisUtil.delString(LOGIN_TOKEN + email);
        return PublicEnums.OK.getResult();
    }




}
